package battleship.ai;

import java.util.*;

import battleship.model.*;



/**
 * A class to hold AI logic for battleship. 
 *
 * implementation: Control Unit calls creates a "computer", then calls userAttack after each time the user makes a move so that the computer can make a counter-attack.
 *
 *
 * @author  David Frick and Friends
 * @version 1.0
 */
 
public class Computer {
        private Shot lastShot;
        private int lastDirection;
        private Grid PlayerGrid;
        
        public Computer(Grid grid) {
        
                //Grid computer = new Grid();   
                lastShot = new Shot(grid);
                PlayerGrid = grid;
                lastDirection = 5;
        }
        
  public Shot userAttack() {
                int direction = 5;

                //check to see if last shot was successful (with a given direction), if so, start there
              if(PlayerGrid.TheGrid[lastShot.x][lastShot.y].Hit() && lastDirection != 5) {
              
            	  
						//look at the cell next to the last shot in the last direction
                        if(checkCell(lastShot.x, lastShot.y, lastDirection)) {
                                direction = lastDirection;
						}
                        
                        //return attack if any empty spaces were found. If not, break away and move along the program
                        switch(direction) {
                                case 0:
                                        lastShot = attack(lastShot.x, (lastShot.y - 1));
										lastDirection = 0;
                                        return attack(lastShot.x, (lastShot.y));
                                case 1:
                                        lastShot = attack((lastShot.x + 1), lastShot.y);
										lastDirection = 1;
                                        return attack((lastShot.x), lastShot.y);
                                case 2:
                                        lastShot = attack(lastShot.x, (lastShot.y + 1));
										lastDirection = 2;
                                        return attack(lastShot.x, (lastShot.y));
                                case 3:
                                        lastShot = attack((lastShot.x - 1), lastShot.y);
										lastDirection = 3;
                                        return attack((lastShot.x), lastShot.y);
								default:
									break;
                        }
                }
			
			//simple version of computer logic, simply attacks all places surrounding a current hit    
                for(int i = 0; i < 10; i++){
                        for(int j = 0; j < 10; j++){
                                if(PlayerGrid.TheGrid[i][j].Hit()) {
                                         
                                        //look up, right, down, and left for an empty space
                                        for(int k = 0; k < 4; k++) {
                                                if(checkCell(i, j, k)) {
                                                        direction = k;
                                                        break;
                                                }
                                        }
                                        
                                        //return attack if any empty spaces were found. If not, break away and move along the program
                                        switch(direction) {
                                                case 0:
                                                        lastDirection = 0;
                                                        lastShot = attack(i, (j - 1));
                                                        return attack(i, (j - 1));
                                                case 1:
                                                        lastDirection = 1;
                                                        lastShot = attack((i + 1), j);
                                                        return attack((i + 1), j);
                                                case 2:
                                                        lastDirection = 2;
                                                        lastShot = attack(i, (j + 1));
                                                        return attack(i, (j + 1));
                                                case 3:
                                                        lastDirection = 3;
                                                        lastShot = attack((i - 1), j);
                                                        return attack((i - 1), j);
                                                default:
                                                        break;
                                                
                                        }
                                }
                        }
                }
                
                
                Random generator = new Random();
                int x,y;
                //find a random empty space...FIRE!
                do {
                        x = generator.nextInt(10);
                        y = generator.nextInt(10);
                } while(PlayerGrid.TheGrid[x][y].IsFiredAt() == true);
                
                lastShot = attack(x, y);//may be used next turn if hit was successful
				lastDirection = 5;
                return attack(x, y);
                
        }

		/**
		 * checkCell returns true if cell the specified cell is empty
		 *
		 * implementation: uses current x, current y, and the direction of the cell to check (0-up, 1-right, 2-down, 3-left)
		 *
		 *
		 * @author  David Frick and Friends
		 * @version 1.0
		 */
        boolean checkCell(int x, int y, int direction) {
                switch(direction) {
                        case 0:
                                if(y > 0) { //prevent checking outside grid
									if(!PlayerGrid.TheGrid[x][y-1].Hit() && !PlayerGrid.TheGrid[x][y-1].IsFiredAt()) {//if cell hasn't been attacked
										return true;
									} else {
										return false;
									}
                                }
								return false;
                        case 1:
                                if(x < 9) {
									if(!PlayerGrid.TheGrid[x + 1][y].Hit() && !PlayerGrid.TheGrid[x + 1][y].IsFiredAt()) {
										return true;
									} else {
										return false;
									}     
                                }
								return false;
                        case 2:
                                if(y < 9) {
									if(!PlayerGrid.TheGrid[x][y+1].Hit() && !PlayerGrid.TheGrid[x][y+1].IsFiredAt()) {
										return true;
									} else {
										return false;
									}
								}
								return false;
                        case 3:
                                if(x > 0) {
									if(!PlayerGrid.TheGrid[x - 1][y].Hit() && !PlayerGrid.TheGrid[x -1][y].IsFiredAt()) {
										return true;
									} else {
										return false;
									}
                                }
								return false;
						default:
							break;
                }
                return false;
        }
        
        
		/**
		 * used for attack to attack each cell
		 *
		 * implementation: uses x and y to fire, then returns (grid, x, y)
		 */
        Shot attack(int x, int y){
                PlayerGrid.TheGrid[x][y].FireAt();
                return new Shot(PlayerGrid, x, y);
                
        }

}

